package org.bcncoding.appengine.droiding.client.widget;

import java.util.List;

import org.bcncoding.appengine.droiding.client.service.AdminService;
import org.bcncoding.appengine.droiding.client.service.AdminServiceAsync;
import org.bcncoding.appengine.droiding.server.pojo.ServiceProviderInfo;

import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.rpc.ServiceDefTarget;
import com.google.gwt.user.client.ui.Composite;

public class ServiceProviderTableWidget extends Composite {

	public class ServiceProviderDataProvider implements DynaTableDataProvider {

		private final AdminServiceAsync admService;

		private int lastMaxRows = -1;

		private List<ServiceProviderInfo> lastProviders = null;

		private int lastStartRow = -1;

		public ServiceProviderDataProvider() {
			admService = (AdminServiceAsync) GWT.create(AdminService.class);
			ServiceDefTarget target = (ServiceDefTarget) admService;
			String moduleRelativeURL = GWT.getModuleBaseURL() + "admin";
			target.setServiceEntryPoint(moduleRelativeURL);
		}

		public void updateRowData(final int startRow, final int maxRows,
				final RowDataAcceptor acceptor) {
			if (startRow == lastStartRow) {
				if (maxRows == lastMaxRows) {
					pushResults(acceptor, startRow, lastProviders);
					return;
				}
			}
			admService.getAllServiceProvider(startRow, maxRows,
					new AsyncCallback<List<ServiceProviderInfo>>() {
						public void onFailure(Throwable caught) {
							acceptor.failed(caught);
						}

						public void onSuccess(List<ServiceProviderInfo> result) {
							lastStartRow = startRow;
							lastMaxRows = maxRows;
							lastProviders = result;
							pushResults(acceptor, startRow, result);
						}

					});
		}

		public void countRowData(final RowDataAcceptor acceptor) {
			admService.countServiceProvider(new AsyncCallback<Integer>() {
				public void onFailure(Throwable caught) {
					acceptor.failed(caught);
				}

				public void onSuccess(Integer result) {
					pushCountResults(acceptor, result);
				}

			});
		}

		public void deleteRowData(String key, final RowDataAcceptor acceptor) {
			admService.deleteServiceProvider(key, new AsyncCallback<Boolean>() {
				public void onFailure(Throwable caught) {
					acceptor.failed(caught);
				}

				public void onSuccess(Boolean result) {
					pushDeleteResults(acceptor, result);
				}

			});
		}

		private void pushResults(RowDataAcceptor acceptor, int startRow,
				List<ServiceProviderInfo> providers) {
			String[][] rows = new String[providers.size()][];
			for (int i = 0, n = rows.length; i < n; i++) {
				ServiceProviderInfo provider = providers.get(i);
				rows[i] = new String[4];
				rows[i][0] = provider.getId();
				rows[i][1] = provider.getName();
				rows[i][2] = provider.getLocation();
				rows[i][3] = "lat: " + provider.getLatitude() + " lng: "
						+ provider.getLongitude();
			}
			acceptor.accept(startRow, rows);
		}

		private void pushCountResults(RowDataAcceptor acceptor, Integer count) {
			acceptor.accept(count);
		}

		private void pushDeleteResults(RowDataAcceptor acceptor, Boolean bool) {
			acceptor.accept(bool);
		}

	}

	private final ServiceProviderDataProvider srvProvider = new ServiceProviderDataProvider();

	private final DynaTableWidget dynaTable;

	public ServiceProviderTableWidget(int visibleRows) {
		String[] columns = new String[] { "Id", "Name", "City", "Coordinates",
				"Edit", "Delete" };
		String[] styles = new String[] { "id", "name", "city", "coords",
				"edit", "delete" };
		dynaTable = new DynaTableWidget(srvProvider, columns, styles,
				visibleRows);
		initWidget(dynaTable);
	}

	@Override
	protected void onLoad() {
		dynaTable.refresh();
	}

}
